home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / games / larn_123 / part04 / tgetent.c < prev   
C/C++ Source or Header  |  1991-08-28  |  10KB  |  396 lines

  1. /************************************************************************
  2.  *                                  *
  3.  *          Copyright (c) 1982, Fred Fish           *
  4.  *              All Rights Reserved             *
  5.  *                                  *
  6.  *  This software and/or documentation is released for public   *
  7.  *  distribution for personal, non-commercial use only.     *
  8.  *  Limited rights to use, modify, and redistribute are hereby  *
  9.  *  granted for non-commercial purposes, provided that all      *
  10.  *  copyright notices remain intact and all changes are clearly *
  11.  *  documented.  The author makes no warranty of any kind with  *
  12.  *  respect to this product and explicitly disclaims any implied    *
  13.  *  warranties of merchantability or fitness for any particular *
  14.  *  purpose.                            *
  15.  *                                  *
  16.  ************************************************************************
  17.  */
  18.  
  19. /*
  20.  *  LIBRARY FUNCTION
  21.  *
  22.  *  tgetent   load buffer with entry for specified terminal
  23.  *
  24.  *  KEY WORDS
  25.  *
  26.  *  termcap functions
  27.  *  utility routines
  28.  *
  29.  *  SYNOPSIS
  30.  *
  31.  *  int tgetent(bp,name)
  32.  *  char *bp;
  33.  *  char *name;
  34.  *
  35.  *  DESCRIPTION
  36.  *
  37.  *  Extracts the entry for terminal <name> from the termcap file
  38.  *  and places it in the character buffer <bp>.   It is currently
  39.  *  assumed that bp is at least 1024 characters.  If the entry in
  40.  *  the termcap file is larger than 1023 characters the excess
  41.  *  characters will be discarded and appropriate status will
  42.  *  be returned.
  43.  *
  44.  *  Also note that since bp is used by other termcap
  45.  *  routines, the storage associated with the termcap entry
  46.  *  cannot be freed until all termcap calls are completed.
  47.  *
  48.  *  Tgetent can be directed to look in a file other than
  49.  *  the default (/etc/termcap) by defining an environment
  50.  *  variable called TERMCAP to be the pathname of the desired
  51.  *  termcap file.  This is useful for debugging new entries.
  52. #ifndef VMS
  53.  *  NOTE: the pathname MUST begin with a '/' character.
  54.  *
  55.  *  Also, if the string assigned to TERMCAP does not begin with
  56.  *  a '/' and if the environment variable TERM matches <name> then
  57.  *  the string assigned to TERMCAP is copied to buffer <bp> 
  58.  *  instead of reading a termcap file.
  59. #endif
  60.  *  
  61.  *  If the termcap entry contains a "tc" string then the termcap
  62.  *  entry named in the string is appended to the buffer (minus the
  63.  *  names).
  64.  *
  65.  *  RETURNS
  66.  *
  67.  *  -1  if the termcap file cannot be opened
  68.  *   0  if no entry in termcap file matches <name>
  69.  *   1  if extraction is successful with no errors
  70.  *   2  if extraction is successful but entry truncated
  71.  *
  72.  *  SEE ALSO
  73.  *
  74.  *  tgetnum   extract numeric type capability
  75.  *  tgetflag  test boolean type capability
  76.  *  tgetstr   get string value of capability
  77.  *
  78.  *  AUTHOR
  79.  *
  80.  *  Fred Fish
  81.  *
  82.  */
  83.  
  84. #include <stdio.h>
  85.  
  86. #define TRUE 1
  87. #define FALSE 0
  88. #define BUFSIZE 1024            /* Assumed size of external buffer */
  89.  
  90. #define NO_FILE  -1         /* Returned if can't open file */
  91. #define NO_ENTRY  0         /* Returned if can't find entry */
  92. #define SUCCESS   1         /* Returned if entry found ok */
  93. #define TRUNCATED 2         /* Returned if entry found but trunc */
  94.  
  95. #ifdef MSDOS
  96. FILE *fopenp();
  97. #endif
  98.  
  99. #define DEFAULT_ROOT "termcap"      /* name without path component */
  100. #ifdef VMS
  101. #define DEFAULT_FILE "sys$library:termcap"
  102. #else
  103. #define DEFAULT_FILE "/etc/termcap" /* default termcap filename */
  104. #endif VMS
  105.  
  106. char *_tcpbuf;              /* Place to remember buffer pointer */
  107.  
  108. /*
  109.  *  PSEUDO CODE
  110.  *
  111.  *  Begin tgetent
  112.  *      Erase any previous buffer contents.
  113.  *      Remember the buffer pointer.
  114.  *      If termcap file is not found then
  115.  *      If buffer was filled anyway then
  116.  *          Return SUCCESS.
  117.  *      Else
  118.  *          Return NO_FILE.
  119.  *      End if
  120.  *      Else
  121.  *      While records left to process
  122.  *          If this is entry is what we want then
  123.  *          Close the termcap file.
  124.  *          If entry was truncated then
  125.  *              Return TRUNCATED status
  126.  *          Else
  127.  *              Return SUCCESS status.
  128.  *          End if
  129.  *          End if
  130.  *      End while
  131.  *      Return NO_ENTRY status.
  132.  *      End if
  133.  *  End tgetent
  134.  *          
  135.  */
  136.  
  137. int tgetent(bp,name)
  138. char *bp;               /* Pointer to buffer (1024 char min) */
  139. char *name;             /* Pointer to terminal entry to find */
  140. {
  141.     FILE *fp, *find_file();
  142.     char *nbp, tc[80];
  143.  
  144.     *bp = (char)NULL;
  145.     _tcpbuf = bp;
  146.     if ((fp = find_file(bp)) == NULL) {
  147.     if (*bp != NULL) {
  148.         return(SUCCESS);
  149.     } else {
  150.         return(NO_FILE);
  151.     }
  152.     } else {
  153.     while (fgetlr(bp,BUFSIZE,fp)) {
  154.         if (gotcha(bp,name)) {
  155.         fclose(fp);
  156.         nbp = &bp[strlen(bp)-1];
  157.         if (*nbp != '\n') {
  158.             return(TRUNCATED);
  159.         } else {
  160.             /* check for a recursive call (i.e. :tc=vt100:)
  161.              * added 18-dec-86 RDE (single recursion...)
  162.              */
  163.             char *area;
  164.             area = &tc[0];
  165.             if (tgetstr("tc", &area) == NULL)       
  166.             return(SUCCESS);
  167.             else {
  168.             fp = find_file(0);  /* know it works and is file */
  169.             while (fgetlr(nbp, BUFSIZE-(nbp-bp), fp)) {
  170.                 if (gotcha(nbp,tc)) {
  171.                 char *cp1, *cp2;    /* scrunch out names */
  172.                 fclose(fp);
  173.                 cp1 = nbp;
  174.                 while (*cp1++ != ':')   /* search for first  */
  175.                     ;
  176.                 cp2 = nbp;
  177.                 while (*cp2++ = *cp1++) /* move the chars.   */
  178.                     ;
  179.                 if (bp[strlen(bp)-1] != '\n') {
  180.                     return(TRUNCATED);
  181.                 } else {
  182.                     return(SUCCESS);
  183.                 }
  184.                 }
  185.             }
  186.             return (NO_ENTRY);
  187.             }
  188.         }
  189.         }
  190.     }
  191.     return(NO_ENTRY);
  192.     }
  193. }
  194.  
  195. /*
  196.  *  INTERNAL FUNCTION
  197.  *
  198.  *  find_file    find the termcap file and open it if possible
  199.  *
  200.  *  KEY WORDS
  201.  *
  202.  *  internal functions
  203.  *  find_file
  204.  *
  205.  *  SYNOPSIS
  206.  *
  207.  *  static FILE *find_file(bp)
  208.  *  char *bp;
  209.  *
  210.  *  DESCRIPTION
  211.  *
  212.  *  Attempts to locate and open the termcap file.  Also handles
  213.  *  using the environment TERMCAP string as the actual buffer
  214.  *  (that's why bp has to be an input parameter).
  215.  *
  216. #ifdef VMS
  217.  *  If TERMCAP is defined as a valid filespec then it will be
  218.  *  opened.  If this fails then the default termcap file will
  219.  *  be used.
  220. #else
  221.  *  If TERMCAP is defined an begins with a '/' character then
  222.  *  it is taken to be the pathname of the termcap file and
  223.  *  an attempt is made to open it.  If this fails then
  224.  *  the default termcap file is used instead.
  225.  *
  226.  *  If TERMCAP is defined but does not begin with a '/' then
  227.  *  it is assumed to be the actual buffer contents provided
  228.  *  that <name> matches the environment variable TERM.
  229. #endif
  230.  *
  231.  *  BUGS
  232.  *
  233.  *  There is currently no way to be sure which termcap
  234.  *  file was opened since the default will always be
  235.  *  tried.
  236.  *
  237.  */
  238.  
  239. /*
  240.  *  PSEUDO CODE
  241.  *
  242.  *  Begin find_file
  243.  *      If there is a TERMCAP environment string then
  244.  *      If the string is not null then
  245.  *          If the string is a pathname then
  246.  *          If that file is opened successfully then
  247.  *              Return its pointer.
  248.  *          End if
  249.  *          Else
  250.  *          If there is a TERM environment string then
  251.  *              If TERM matches <name> then
  252.  *              Copy TERMCAP string to buffer.
  253.  *              Return NULL for no file.
  254.  *              End if
  255.  *          End if
  256.  *          End if
  257.  *      End if
  258.  *      End if
  259.  *      Open default termcap file and return results.
  260.  *  End find_file
  261.  *
  262.  */
  263.  
  264. static FILE *find_file(bp)
  265. char *bp;
  266. {
  267.     FILE *fp, *fopen();
  268.     char *cp, *ncp, *getenv();
  269.  
  270.     if ((cp = getenv("TERMCAP")) != NULL) {
  271.     if (*cp != NULL) {
  272. #ifdef VMS
  273.         if ((fp = fopen(cp, "r")) != NULL)
  274.         return(fp);
  275. #else
  276.         if (*cp == '/' || *cp == '\\') {
  277.         if ((fp = fopen(cp,"r")) != NULL) {
  278.             return(fp);
  279.         }
  280.         } else {
  281.         if ((ncp = getenv("TERM")) != NULL) {
  282.             if (strcmp(cp,ncp) == 0) {
  283.             strcpy(bp,cp);
  284.             return((FILE *)NULL);
  285.             }
  286.         }
  287.         }
  288. #endif
  289.     }
  290.     }
  291.     /*
  292.      * Try current directory, then /etc/termcap
  293.      */
  294.     if (fp = fopen(DEFAULT_ROOT, "r"))
  295.         return fp;
  296.     else
  297. #ifdef MSDOS
  298.     if (fp = fopen(DEFAULT_FILE, "r") )
  299.             return fp;
  300.         else    /* try along the PATH */
  301.         return( fopenp(DEFAULT_ROOT, "r", NULL));
  302. #else
  303.         return (fopen(DEFAULT_FILE, "r"));
  304. #endif
  305. }
  306.  
  307.  
  308. /*
  309.  *  INTERNAL FUNCTION
  310.  *
  311.  *  gotcha   test to see if entry is for specified terminal
  312.  *
  313.  *  SYNOPSIS
  314.  *
  315.  *  gotcha(bp,name)
  316.  *  char *bp;
  317.  *  char *name;
  318.  *
  319.  *  DESCRIPTION
  320.  *
  321.  *  Tests to see if the entry in buffer bp matches the terminal
  322.  *  specified by name.  Returns TRUE if match is detected, FALSE
  323.  *  otherwise.
  324.  *
  325.  */
  326.  
  327. /*
  328.  *  PSEUDO CODE
  329.  *
  330.  *  Begin gotcha
  331.  *      If buffer character is comment character then
  332.  *      Return FALSE since remainder is comment
  333.  *      Else
  334.  *      Initialize name scan pointer.
  335.  *      Compare name and buffer until end or mismatch.
  336.  *      If valid terminators for both name and buffer strings
  337.  *          Return TRUE since a match was found.
  338.  *      Else
  339.  *          Find next non-name character in buffer.
  340.  *          If not an alternate name separater character
  341.  *          Return FALSE since no more names to check.
  342.  *          Else
  343.  *          Test next name and return results.
  344.  *          End if
  345.  *      End if
  346.  *      End if
  347.  *  End gotcha
  348.  *
  349.  */
  350.  
  351. gotcha(bp,name)
  352. char *bp;
  353. char *name;
  354. {
  355.     char *np;
  356.  
  357.     if (*bp == '#') {
  358.     return(FALSE);
  359.     } else {
  360.     np = name;
  361.     while (*np == *bp && *np != NULL) {np++; bp++;}
  362.     if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) {
  363.         return(TRUE);
  364.     } else {
  365.         while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;}
  366.         if (*bp != '|') {
  367.         return(FALSE);
  368.         } else {
  369.         return(gotcha(++bp,name));
  370.         }
  371.     }
  372.     }
  373. }
  374.  
  375. #ifdef MSDOS
  376. /*
  377.  * index(buffer, char)
  378.  * Find character in buffer.  Return the pointer
  379.  * to it. Shouldn't be necessary to write this
  380.  * myself but VMS didn't.  Oh Well...
  381.  * Used by lots of files in the termcap library.
  382.  * Rich Ellison, 16-DEC-1986
  383.  */
  384. char
  385. *index(buf, ch)
  386. char    *buf;
  387. char    ch;
  388. {
  389.     register int    c;
  390.     while ((c= *buf++) != '\0')
  391.         if (c == ch)
  392.             return (buf-1);
  393.     return (NULL);
  394. }
  395. #endif
  396.